#pragma once

#include "VLNObserverImpl.h"
#include <map>

template <typename ReturnT, typename ParamT>
class CVLNObserverImplBase;

template <typename ReturnT, typename ParamT>
class CVLNReceiverImplBase
{
public:
	virtual void AddObserver(CVLNObserverImplBase<ReturnT, ParamT>* observer) = 0;
	virtual void RemoveObserver() = 0;
	virtual ReturnT Receive(ParamT param) = 0;
	virtual ReturnT Respond(ParamT param, CVLNObserverImplBase<ReturnT, ParamT>* observer) = 0;
};

template <typename ReturnT, typename ParamT>
class CVLNReceiverImpl : public CVLNReceiverImplBase<ReturnT, ParamT>
{
public:
	CVLNReceiverImpl()
		: count_(0)
	{}

	virtual ~CVLNReceiverImpl()	{}

	virtual void AddObserver(CVLNObserverImplBase<ReturnT, ParamT>* observer)
	{
		observers_[count_] = observer;
		count_++;
	}

	virtual void RemoveObserver()
	{
		ObserversMap::iterator it = observers_.begin();
		for (; it != observers_.end(); ++it)
		{
			it->second->RemoveReceiver(this);
		}
	}

	virtual ReturnT Receive(ParamT param)
	{
		return ReturnT();
	}

	virtual ReturnT Respond(ParamT param, CVLNObserverImplBase<ReturnT, ParamT>* observer)
	{
		return ReturnT();
	}

protected:
	typedef std::map<int, CVLNObserverImplBase<ReturnT, ParamT>*> ObserversMap;
	ObserversMap observers_;
	int count_;
};